import asyncio
import tornado.ioloop
import tornado.web
import tornado.websocket
import json
from lib.read_yaml import read_yaml
from logger import logger
from route import route

env = read_yaml('./env.yaml')

class ApplicationHandler(tornado.websocket.WebSocketHandler):
    def on_message(self, message):
        try:
            data = json.loads(message)
            logger("⏬️ Request Data:\t", data)
            if "event" not in data:
                raise Exception("Request data format error: key 'event' must be provided.")
            logger("⏳ Processing...")
            def write_message(result_data):
                result = {
                    "event": data["event"],
                    "response_id": data["request_id"] if "request_id" in data else None,
                    "status": 200,
                    "data": result_data,
                }
                self.write_message(json.dumps(result))
                logger("⏫️ Response Data:\t", result)
            result = route(data, write_message)
            if result:
                write_message(result)
            self.close()
        except Exception as e:
            error = {
                "event": data["event"] if "event" in data else None,
                "response_id": data["request_id"] if "request_id" in data else None,
                "status": 400,
                "msg": str(e),
            }
            logger("🔴 Error:\t", error)
            self.write_message(json.dumps(error))
            #for debug:
            raise e
            self.close()

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (env["PATH"], ApplicationHandler),
        ]
        super(Application, self).__init__(handlers)

if __name__ == "__main__":
    app = Application()
    app.listen(env["PORT"])
    path = env["PATH"][:-1] if env["PATH"][-1] == "/" else env["PATH"]
    logger(f"🟢 \033[91m\033[47m\033[3m\033[1m Agent\033[34mly\033[30m.Tech \033[0m WebSocket Service start serving on 0.0.0.0{ path }:{ env['PORT'] } or 127.0.0.1{ path }:{ env['PORT'] }...")
    if env["DEBUG"]:
        logger(f"🐞 Debug Mode: ON")
    tornado.ioloop.IOLoop.current().start()